/******************************************************************************
 **
 **    LISA Confidential
 **
 **    Source Materials
 **
 **    (C) COPYRIGHT LISA 2008-2009
 **
 **
 **  File Name:      GetProcessedProcessCommand.java
 **  Description:
 **  Date:           2008-10-28
 **  Author:         LisaQian
 ******************************************************************************/
package com.ti.andon.workflow.command;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.jbpm.JbpmContext;
import org.jbpm.JbpmException;
import org.jbpm.command.Command;
import org.jbpm.graph.exe.ProcessInstance;

public class GetProcessedProcessCmd implements Command
{
	/**
	 *  Serial Version ID.
	 */
	private static final long serialVersionUID = 2597098752164361632L;

	private static Log logger = LogFactory.getLog(GetProcessedProcessCmd.class);
	
	/**
	 * The process definition name
	 */
	String processDefinitionName;


	/**
	 * The user who processed the task instance
	 */
	Long processorId;

	/**
	 * The left boundary of the task instance end time, with format yyyy-mm-dd
	 */
	String startTime;

	/**
	 * The right boundary of the task instance end time, with format yyyy-mm-dd
	 */
	String endTime;

	private static final Log log = LogFactory
	.getLog(GetProcessedProcessCmd.class);
	
	/**
	 * @param expenseType
	 * @param ExpenseCategory
	 * @param processor
	 * @param startTime
	 * @param endTime
	 * @return The List of the processed process instance business key and its
	 *         current task instance name
	 */
	public GetProcessedProcessCmd(String processDefintionName,
			 Long processorId, String startTime,
			String endTime) {
		this.processDefinitionName = processDefintionName;
		this.startTime = startTime;
		this.endTime = endTime;
		this.processorId = processorId;
	}
	
	/**
	 * Gets the processed instance information, including business key and status (currently no status info).
	 * @param jbpmContext
	 * @return the processed instance information including business key and status (currently no status info).
	 * */
	public Object execute(JbpmContext jbpmContext) throws Exception
	{
		ArrayList result = new ArrayList();
		List processInstance = findProcessedProcess(jbpmContext);
		Iterator iterProcessInstance = processInstance.iterator();
		ArrayList temp = new ArrayList();
		while (iterProcessInstance.hasNext())
		{
			ProcessInstance pi = (ProcessInstance) iterProcessInstance.next();
			if (!temp.contains(pi) && pi.getProcessDefinition().getName().equals(this.processDefinitionName))
			{
				temp.add(pi);

				String[] keyAndStatus = new String[] { "", "" };
				keyAndStatus[0] = pi.getKey();
				// TODO if needed, adds the status information.
				result.add(keyAndStatus);
			}
		}
		temp.clear();
		return result;

	}

	/**
	 * Fetches the processed processInstances from the database, according to the criteria.
	 * @param jbpmContext
	 * @return the list of the processed processInstance from the database according to the criteria.
	 * */
	public List findProcessedProcess(JbpmContext jbpmContext)
	{
		List result = null;
		try
		{
			Query query = jbpmContext.getSession().getNamedQuery("GraphSession.findProcessedProcess");
			if (null != processorId)
			{
				query.setString("actorId", this.processorId.toString());
				if (null == this.startTime || this.startTime.equals(""))
				{
					query.setString("startTime", "1900-01-01");
				}
				else
				{
					query.setString("startTime", this.startTime);
				}
				if (null == this.endTime || this.endTime.equals(""))
				{
					query.setString("endTime", "2050-12-31");
				}
				else
				{
					query.setString("endTime", this.endTime);
				}
				result = query.list();
			}
			else
			{
				logger.error("GetProcessedProcessCmd.findProcessedProcess() : processorId can not be null!!!");
			}
		}
		catch (Exception e)
		{
			log.error("GetProcessedProcessCmd.findProcessedProcess() : Error occurred : " + e.toString());
			throw new JbpmException(
					"GetProcessedProcessCmd.findProcessedProcess() : couldn't get processed request for actor '"
							+ this.processorId + "' between " + this.startTime + " and " + this.endTime, e);
		}
		return result;
	}

}
